import 'dart:async';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter_blue/flutter_blue.dart';
import 'package:fluttertoast/fluttertoast.dart';

import 'config.dart';

class BlueMaestroService {
  FlutterBlue _flutterBlue = FlutterBlue.instance;

  // 连接的蓝牙实例
  BluetoothDevice _blueDevice;

  // mtu
  int _mtu = 247;

  // deviceId
  String _blueDeviceId = "";

  // 发现的服务
  List<BluetoothService> _discoverServices = [];

  // 监听实例
  StreamSubscription<BluetoothState> _blueStateSubscr;
  StreamSubscription<BluetoothDeviceState> _deviceStateSubscr;

  // 固件地址
  String _url_040 =
      'https://file-test.maestro.love/e9d02ede-71b0-4804-9cdf-1636374f5f7a.gbl';
  String _url_050 =
      'https://file-test.maestro.love/835ba414-ce8a-4c3a-98e7-7bf879892aba.gbl';
  String _url = "";

  // 蓝牙是否在ota状态
  bool _blueOTAState = false;
  bool _isBlueConnect = false;

  // control 特性
  BluetoothCharacteristic otaController;

  // write data 特性
  BluetoothCharacteristic otaWrite;

  // 扫描附近的蓝牙设备
  void scanDevices(callback(List<ScanResult> list)) {
    _flutterBlue.startScan(timeout: Duration(seconds: 4));
    _flutterBlue.scanResults.listen((results) {
      List<ScanResult> resultList = [];
      for (ScanResult r in results) {
        if (r.device.name.isNotEmpty ||
            r.device.id.toString().indexOf("84") >= 0) {
          // print('${r.device.name} found! rssi: ${r.rssi}');
          resultList.add(r);
        }
      }
      callback(resultList);
    });
  }

  // 连接设备
  String connectDevice(BluetoothDevice device) {
    _flutterBlue.stopScan();
    setPageState("正在连接 ${device.name}");
    _blueStateSubscr?.cancel();
    _deviceStateSubscr?.cancel();
    _blueDevice = device;
    _blueDeviceId = device.id.toString();
    _blueStateSubscr = _flutterBlue.state.listen((BluetoothState state) {
      print("flutterBlue 状态变更 = $state");
    });
    _deviceStateSubscr = _blueDevice.state.listen((event) async {
      print("蓝牙状态变更 = $event");
      try {
        if (event == BluetoothDeviceState.connected) {
          setPageState("蓝牙已连接");
          _isBlueConnect = true;
        } else if (event == BluetoothDeviceState.disconnected) {
          _isBlueConnect = false;
          if (_blueOTAState) {
            setPageState("进入OTA模式,蓝牙已断开,准备重连");
          } else {
            setPageState("蓝牙已断开");
          }
        }
      } catch (e) {
        setPageState("蓝牙连接失败");
      }
    });
    device.connect();
    return "当前连接的蓝牙: ${device.name} IP: $_blueDeviceId";
  }

  setMtu() async {
    // final mtu = await _blueDevice.mtu.first;
    await _blueDevice.requestMtu(_mtu);
    var mtuChanged = Completer<void>();
    // mtu is of type 'int'
    var mtuStreamSubscription = _blueDevice.mtu.listen((mtu) {
      print("mtu = $mtu ${_mtu}");
      if (mtu == _mtu) mtuChanged.complete();
    });
    await mtuChanged.future; // set timeout and catch exception
    mtuStreamSubscription.cancel();
  }

  // 发现服务
  Future<List<BluetoothService>> discoverService() async {
    print("蓝牙状态 ${_blueDevice.state.toString()}");
    if (_isBlueConnect) {
      setPageState("发现服务");
      List<BluetoothService> services;
      if (_blueOTAState) {
        _discoverServices = [];
        otaController = null;
        otaWrite = null;
        print("--发现服务 ota模式 start");
        var blueDev = await _flutterBlue.connectedDevices;
        BluetoothDevice bd = blueDev[0];
        print("--发现服务 ota模式 ${blueDev.length}");
        services = await bd.discoverServices();
        _discoverServices = services;
        await Future.delayed(Duration(seconds: 2));
        otaController = getCharacter(
            Config.maestroOTAService_UUID, Config.maestroOTAController_UUID);
        otaWrite = getCharacter(
            Config.maestroOTAService_UUID, Config.maestroOTAWrite_UUID);

        print("--发现服务,设置ota成功 ${otaController.isNotifying}");
      } else {
        services = await _blueDevice.discoverServices();
        print("发现服务 = ${services.length}");
        _discoverServices = services;
      }
      return services;
    } else {
      setPageState("蓝牙未连接, 无法发现服务");
      return [];
    }
  }

  // 获取服务的特性
  BluetoothCharacteristic getCharacter(String serviceStr, String characterStr) {
    if (_discoverServices.length == 0) {
      setPageState("无服务");
      return null;
    }
    BluetoothService service = _discoverServices
        .firstWhere((element) => element.uuid.toString() == serviceStr);
    print("获取服务 $serviceStr - $characterStr = $service");
    List<BluetoothCharacteristic> characters = service.characteristics;
    print("获取特性 $serviceStr - $characterStr = $characters");
    BluetoothCharacteristic s = characters?.firstWhere(
        (element) => element.uuid.toString() == characterStr,
        orElse: () => null);

    return s;
  }

  // ota 发送0, 写入固件, 发送3,发送4,重启蓝牙
  startOTA() async {
    otaController = getCharacter(
        Config.maestroOTAService_UUID, Config.maestroOTAController_UUID);
    print("发送指令0x00");
    _blueOTAState = true;
    await otaController.write([0], withoutResponse: false);
  }

  closeOTA() async {
    print("发送指令0x04");
    await otaController.write([4], withoutResponse: false);
    _blueOTAState = false;
  }

  // 获取写入ota的write data
  getOTADataCharacter() async {
    if (_blueOTAState) {
      _discoverServices = await _blueDevice.discoverServices();
      await Future.delayed(Duration(milliseconds: 200));
      otaWrite = getCharacter(
          Config.maestroOTAService_UUID, Config.maestroOTAWrite_UUID);
      if (otaWrite != null) {
        setPageState("otaWrite获取成功");
      } else {
        setPageState("otaWrite获取失败");
      }
    }
  }

  otaWriteTest(ByteData byteData, callback(double pro)) async {
    // 字节流转Uint8数组形式
    Uint8List byteList = Uint8List.sublistView(byteData);
    print("固件大小 = ${byteData.lengthInBytes} ${byteList.length}");
    // 二维数组,存放分段字节流
    List<List<int>> commandList = [];
    List<int> temp = [];
    int j = 0;
    for (int i = 0; i < byteData.lengthInBytes; i++) {
      temp.add(byteList[i]);
      j++;
      if (j >= 244) {
        commandList.add(temp);
        j = 0;
        temp = [];
      }
    }
    commandList.add(temp);
    // 获取ota write 特性
    // BluetoothCharacteristic otaWrite = getCharacter(Config.maestroOTAService_UUID, Config.maestroOTAWrite_UUID);
    // 写入
    // await send00();
    for (int i = 0; i < commandList.length; i++) {
      // print("-- 第 $i 个长度 = ${commandList[i].length}");
      await otaWrite.write(commandList[i], withoutResponse: false);
      await Future.delayed(Duration(milliseconds: 10));
      callback((i / commandList.length * 1000).floor() / 1000);
    }
    await send03();
  }

  send00() async {
    try {
      await Future.delayed(Duration(milliseconds: 500));
      // 发送 开始指令 0x00
      print("发送指令0x00 = ${otaController != null}");
      await otaController.write([0], withoutResponse: false);
      await Future.delayed(Duration(milliseconds: 500));
    } catch (e) {
      print("发送00失败 = $e");
    }
  }

  // 测试发送03指令
  send03() async {
    try {
      await Future.delayed(Duration(milliseconds: 500));
      // 发送 开始指令 0x00
      print("发送指令0x03 = ${otaController != null}");
      await otaController.write([3], withoutResponse: false);
    } catch (e) {
      print("发送03失败 = $e");
    }
  }

  // 断开连接
  disconnect() {
    setPageState("断开连接");
    // if (_blueOTAState) {
    //   closeOTA();
    // }
    _blueOTAState = false;
    _blueStateSubscr?.cancel();
    _deviceStateSubscr?.cancel();
    _blueDevice.disconnect();
    _blueDeviceId = null;
    _blueDevice = null;
  }

  setPageState(String string) {
    Fluttertoast.showToast(
      msg: string,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.TOP,
    );
  }
}
